#pragma once
#include "Object.h"
#include "Light.h"
#include "misc.h"
#include "vector4.h"
#include "C3DS_Loader.h"
#include "Material.h"
#include <vector>
#include <string>
#include "Camera.h"


namespace RayTrace{

	class CScene
	{
		friend class C3DS_Loader;

	public:
		CScene(void);
		~CScene(void);

	


		//	bool IsLighten(vector3 p,vector3 light);
	public:
		struct InterSectInf
		{
			size_t objectIndex;
			size_t faceIndex;
			double dist;
		};

		class FaceIterator:public Iterator
		{
		public:
			FaceIterator();
			FaceIterator(CScene * Scene);
			~FaceIterator(void);
			void initial(CScene * Scene);
			void first();
			bool isDone();
			void next();
			void nextIntersect(const Ray& ray);
			void firstIntersect(const Ray& ray);
			size_t materialIndex();
			size_t objectindex();
			const Face& face();
			CTriangle triangle();
			CMaterial material();
			vector3 GetNormalFromBarycentric(const vector3& barycentric);
			bool operator ==(const FaceIterator& )const;
			

		protected:
			CScene * pScene;
			size_t mObjectIndex;
			Object::FaceIterator iter;
		};
		
	public:
		std::vector<vector4> mRenderBuf;

	protected:
		std::vector<CLight* >  mLights;
		vector4	mAbmientColor;
		vector3	mEyepoint;
		Screen	mProjectSreen;
		int		mWidth,mHeight;
		

		std::string modelname;		// The name of the model
		int totalVerts;			// Total number of vertices in the model
		int totalFaces;			// Total number of faces in the model
		bool shownormals;		// True: show the normals
		std::vector<CMaterial> mMaterials;	// The array of materials
		std::vector<Object> mObjects;		// The array of objects in the model
		vector3 pos;				// The position to move the model to
		vector3 rot;				// The angles to rotate the model
		float scale;			// The size you want the model scaled to
		bool lit;				// True: the model is lit
		bool visible;			// True: the model gets rendered
		C3DS_Loader fileLoader;
		CCamera mCamera;



	public:
		void Init(int w,int h);
		void Render(void);
		void Load(std::string name);	// Loads a model
		size_t GetObjectsNum(){return mObjects.size();}
		size_t GetMaterialsNum(){return mMaterials.size();}
		void Statistics();//generate bounding box ...
		void SetCamera(float eyex,float eyey,float eyez,
			float upx,float upy,float upz,
			float centerx,float centery,float centerz,
			float near,
			float ratio,
			float fovy);
		CCamera& GetCamera(){return mCamera;}
		bool InterSect(const Ray& ray,InterSectInf & inf);

	protected:
		void SetLights();
		void SetViewProjSreen();
		vector4 RecCalculateColor(RayTrace::Ray tmpRay, int rec);
	};
}